package com.health.mapp.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse.Credentials;
import com.health.commons.PropertiesService;
import com.health.mapp.utils.PropertiesUtil;

public class ImgUpload extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = -4451502459409874160L;
	private static Logger logger = Logger.getLogger(ImgUpload.class);
    static Map<String,String> OSMap= new HashMap<String,String>();
    static Map<String,String> pathMap= new HashMap<String,String>();
	/**
	 * Constructor of the object.
	 */
	public ImgUpload() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		// Put your code here
	}

	/**
	 * The doGet method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		  doPost(request, response);
	}

	protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	/**
	 * The doPost method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to
	 * post.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		   String path = request.getRealPath("/upload") + "/";
	        File dir = new File(path);
	        if (!dir.exists()) {
	            dir.mkdir();
	        }
	       logger.debug("path=" + path);
	       request.setCharacterEncoding("UTF-8");  //设置编码
	       
	       PrintWriter printWriter = response.getWriter();
	       response.setContentType("application/json");
	       response.setCharacterEncoding("utf-8");
	       HashMap<String, Object> res = new HashMap<String, Object>();
		   
		   String copy ="";
	 
	        //获得磁盘文件条目工厂
	        DiskFileItemFactory factory = new DiskFileItemFactory();

	        //如果没以下两行设置的话,上传大的文件会占用很多内存，
	        //设置暂时存放的存储室,这个存储室可以和最终存储文件的目录不同
	        /**
	         * 原理: 它是先存到暂时存储室，然后再真正写到对应目录的硬盘上，
	         * 按理来说当上传一个文件时，其实是上传了两份，第一个是以 .tem 格式的
	         * 然后再将其真正写到对应目录的硬盘上
	         */
	        factory.setRepository(dir);
	        //设置缓存的大小，当上传文件的容量超过该缓存时，直接放到暂时存储室
	        factory.setSizeThreshold(1024 * 1024);
	        //高水平的API文件上传处理
	        ServletFileUpload upload = new ServletFileUpload(factory);
	        
	        try {
	        	
	            List<FileItem> list = upload.parseRequest(request);
	            FileItem picture = null;
	            
	            //自定义上传图片的名字为userId.jpg
	            String fileName = "";
				
	            for (FileItem item : list) {
	                //获取表单的属性名字
	                String name = item.getFieldName();
	                //如果获取的表单信息是普通的 文本 信息
	                if (item.isFormField()) {
	                    //获取用户具体输入的字符串
/*	                	String value =  new String(item.getString().getBytes("UTF-8"));  
	                    request.setAttribute(name, value);
	                    logger.debug("name=" + name + ",value=" + value);*/
	                } else {
	                    picture = item;
	                    fileName= picture.getName();
	                }
	            }
	            String tailSuffix = getExtension(fileName);
	            
	            long timeradom= System.currentTimeMillis();
	            
	            copy="trainingEnterIcon/"+timeradom+tailSuffix;
	            
	            String destPath = path + timeradom+tailSuffix;
	            logger.debug("destPath=" + destPath);

	            //真正写到磁盘上
	            File file = new File(destPath);
	            OutputStream out = new FileOutputStream(file);
	            InputStream in = picture.getInputStream();
	            int length = 0;
	            byte[] buf = new byte[1024];
	            // in.read(buf) 每次读到的数据存放在buf 数组中
	            while ((length = in.read(buf)) != -1) {
	                //在buf数组中取出数据写到（输出流）磁盘上
	                out.write(buf, 0, length);
	            }
	            in.close();
	            out.close();
	            String DIR ="trainingEnterIcon/";
				uploadByOssShare( file, DIR,copy);
				file.delete();
			    res.put("errorCode", 0);
			    res.put("iconPhotoUrl", DIR+ timeradom+tailSuffix);
			    res.put("errorMsg","操作成功");
				
	        } catch (FileUploadException e1) {
	            logger.error("", e1);
	            res.put("errorCode", -1);
			    res.put("iconPhotoUrl", "");
			    res.put("errorMsg","操作失败");
	        } catch (Exception e) {
	            logger.error("", e);
	            res.put("errorCode", -1);
			    res.put("iconPhotoUrl", "");
			    res.put("errorMsg","操作失败");
	        }
	        
	    	//相对URI
	        printWriter.write(JSON.toJSONString(res));
	        printWriter.flush();
	        
	}
	
    public static String getExtension(String fileName) throws Exception {

        if (null != fileName) {
            int pos = fileName.lastIndexOf(".");
            if (pos > 0) {
                return fileName.substring(pos);
            }

        }
        return "";

    }
    
    
    public static void main(String[] args) {
		try {
			System.out.println(getExtension("trainingEnterIcon/7/1528102229505.gif"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static String getExtensionName(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length() - 1))) {
				return filename.substring(dot + 1);
			}
		}
		return filename;
	}

	/**
	 * Initialization of the servlet. <br>
	 * 
	 * @throws ServletException
	 *             if an error occurs
	 */
	public void init() throws ServletException {
		
		/*	logger.debug("upload init...");
		     getOSInfo();
		      String   file_real_path=this.getServletContext().getRealPath("/");  
		      
		      if (OSMap.get("os.name").toString().contains("Windows"))
				{

		    	  pathMap= PropertiesUtil.createConfig_Upload_Map();
					 
					 
										
				}
				else if (OSMap.get("os.name").toString().contains("Linux") || OSMap.get("os.name").toString().contains("linux")|| OSMap.get("os.name").toString().contains("Unix")||OSMap.get("os.name").toString().contains("unix")) 
				{
							
					  pathMap= PropertiesUtil.createConfig_Upload_Map();
				 
				}
		      */
	    	  
	}

	/**
	 * 获取系统属性集
	 *  
	 * @return
	 */
	public void getOSInfo()
	{
		
		
		
		 Properties props=System.getProperties(); //获得系统属性集
		 
		 
		 //操作系统名称   
		 OSMap.put("os.name", props.getProperty("os.name"));
		 //操作系统构架   
		 OSMap.put("os.arch", props.getProperty("os.arch"));
		 //操作系统版本  
		 OSMap.put("os.version", props.getProperty("os.version"));
		 //Java 运行时环境版本 
		 OSMap.put("java.version", props.getProperty("java.version"));
		  
		// java.vendor Java 运行时环境供应商
		 OSMap.put("java.vendor", props.getProperty("java.vendor"));
		 // Java 供应商的 URL 
		 OSMap.put("java.vendor.url", props.getProperty("java.vendor.url"));
		//  Java 安装目录 
		 OSMap.put("java.home", props.getProperty("java.home"));
		  //Java 虚拟机规范版本 
		 OSMap.put("java.vm.specification.version", props.getProperty("java.vm.specification.version"));
		//  Java 虚拟机规范供应商 
		 OSMap.put("java.vm.specification.vendor", props.getProperty("java.vm.specification.vendor"));
		 // Java 虚拟机规范名称 
		 OSMap.put("java.vm.specification.name", props.getProperty("java.vm.specification.name"));
		  //Java 虚拟机实现版本 
		 OSMap.put("java.vm.version", props.getProperty("java.vm.version"));
		  //Java 虚拟机实现供应商 
		 OSMap.put("java.vm.vendor", props.getProperty("java.vm.vendor"));
		 // Java 虚拟机实现名称 
		 OSMap.put("java.vm.name", props.getProperty("java.vm.name"));
		  //Java 运行时环境规范版本 
		 OSMap.put("java.specification.version", props.getProperty("java.specification.version"));
		  //Java 运行时环境规范供应商 
		 OSMap.put("java.specification.vendor", props.getProperty("java.specification.vendor"));
		  //Java 运行时环境规范名称 
		 OSMap.put("java.specification.name", props.getProperty("java.specification.name"));
		 // Java 类格式版本号 
		 OSMap.put("java.class.version", props.getProperty("java.class.version"));
		  //Java 类路径 
		 OSMap.put("java.class.path", props.getProperty("java.class.path"));
		//  加载库时搜索的路径列表
		 OSMap.put("java.library.path", props.getProperty("java.library.path"));
		 // 默认的临时文件路径 
		 OSMap.put("java.io.tmpdir", props.getProperty("java.io.tmpdir"));
		  //要使用的 JIT 编译器的名称 
		 OSMap.put("java.compiler", props.getProperty("java.compiler"));
		 
		 //一个或多个扩展目录的路径 
		 OSMap.put("java.ext.dirs", props.getProperty("java.ext.dirs"));
	 
		 
		 //文件分隔符（在 UNIX 系统中是“/”） 
		 OSMap.put("jfile.separator ", props.getProperty("file.separator "));
		 
		 //路径分隔符（在 UNIX 系统中是“:”） 
		 OSMap.put("path.separator", props.getProperty("path.separator"));
		 
		 //行分隔符（在 UNIX 系统中是“/n”） 
		 OSMap.put("line.separator ", props.getProperty("line.separator "));
		 
		 //用户的账户名称 
		 OSMap.put("user.name ", props.getProperty("user.name "));
		 // 用户的主目录 
		 OSMap.put("user.home", props.getProperty("user.home"));
		//  用户的当前工作目录 
		 OSMap.put("user.dir", props.getProperty("user.dir"));

 
		
	}
	
	
	
    public static void uploadByOssShare(File dst, String DIR,String backUpName) {

    	logger.fatal("uploadByOss start....................");
        String accessKeyId = PropertiesService.getString("oss.accessKeyId").trim();
        String accessKeySecret = PropertiesService.getString("oss.accessKeySecret").trim();
        String roleArn = PropertiesService.getString("oss.roleReadWrite").trim();
        String roleSessionName = PropertiesService.getString("oss.roleSessionName").trim();
        String endpoint = PropertiesService.getString("oss.endpoint").trim();
        String bucketName = PropertiesService.getString("oss.bucketName").trim();
        
        String policy = "{\n" +
                "	\"Version\": \"1\",\n" +
                "	\"Statement\": [\n" +
                "		{\n" +
                "			\"Effect\": \"Allow\",\n" +
                "		    \"Action\": [\n" +
                "		    	\"oss:ListObjects\",\n" +
                "		    	\"oss:GetObject\"\n" +
                "		    ],\n" +
                "		    \"Resource\": [\n" +
                "		    	\"acs:oss:*:*:li-qiao\",\n" +
                "		   		\"acs:oss:*:*:li-qiao/*\"\n" +
                "		    ]\n" +
                "		},\n" +
                "		{\n" +
                "			\"Effect\": \"Allow\",\n" +
                "			\"Action\": [\n" +
                "				\"oss:AbortMultipartUpload\",\n" +
                "				\"oss:PutObject\"\n" +
                "			],\n" +
                "			\"Resource\": [\n" +
                "				\"acs:oss:*:*:li-qiao\",\n" +
                "				\"acs:oss:*:*:li-qiao/*\"\n" +
                "			]\n" +
                "		}\n" +
                "   ]\n" +
                "}";

        ProtocolType protocolType = ProtocolType.HTTPS;
        Credentials credentials = null;
        try {
            final AssumeRoleResponse response = assumeRole(accessKeyId, accessKeySecret,
                    roleArn, roleSessionName, policy, protocolType);

            if (null != response) {
                credentials = response.getCredentials();


                if (null != credentials) {
                    String accessKeyIdByToken = credentials.getAccessKeyId();
                    String accessKeySecretByToken = credentials.getAccessKeySecret();
                    String securityByToken = credentials.getSecurityToken();
                    OSSClient client = new OSSClient(endpoint, accessKeyIdByToken, accessKeySecretByToken, securityByToken);


                    InputStream content = null;
                    try {
                    	
                    	String fileName=dst.getName();
                        content = new FileInputStream(dst);

                        ObjectMetadata meta = new ObjectMetadata();

                        meta.setContentLength(dst.length());
                        
                        meta.setCacheControl("no-cache");
                        meta.setHeader("Pragma", "no-cache");
                        meta.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
                        meta.setContentDisposition("inline;filename=" + fileName);
                        
                        /*meta.setContentDisposition("inline");
                        meta.setContentType("text/html");*/
                        String key = DIR + dst.getName();
                        
                        logger.fatal("key:" + key);
                        PutObjectResult result = client.putObject(bucketName, key, content, meta);
              
                        logger.fatal(result);

                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } else {
                	logger.fatal("credentials is " + credentials);
                }
            } else {

            	logger.fatal("response is " + response);

            }
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        }

        logger.fatal("uploadByOss end....................");

    }
    
    

	public static String getcontentType(String filenameExtension) {
		if (filenameExtension.equalsIgnoreCase("bmp")) {
			return "image/bmp";
		}
		if (filenameExtension.equalsIgnoreCase("gif")) {
			return "image/gif";
		}
		if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg")
				|| filenameExtension.equalsIgnoreCase("png")) {
			return "image/jpeg";
		}
		if (filenameExtension.equalsIgnoreCase("html")) {
			return "text/html";
		}
		if (filenameExtension.equalsIgnoreCase("txt")) {
			return "text/plain";
		}
		if (filenameExtension.equalsIgnoreCase("vsd")) {
			return "application/vnd.visio";
		}
		if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) {
			return "application/vnd.ms-powerpoint";
		}
		if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) {
			return "application/msword";
		}
		if (filenameExtension.equalsIgnoreCase("xml")) {
			return "text/xml";
		}
		return "image/jpeg";
	}


    static AssumeRoleResponse assumeRole(String accessKeyId,
                                         String accessKeySecret, String roleArn, String roleSessionName,
                                         String policy, ProtocolType protocolType) throws Exception {
        IClientProfile profile = DefaultProfile.getProfile(
                PropertiesService.getString("oss.region").trim(), accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);

        final AssumeRoleRequest request = new AssumeRoleRequest();
        request.setActionName("AssumeRole");
        request.setVersion(PropertiesService.getString("oss.stsApiVersion").trim());
        request.setMethod(MethodType.POST);
        request.setProtocol(protocolType);
        request.setRoleArn(roleArn);
        request.setRoleSessionName(roleSessionName);
        request.setPolicy(policy);
        AssumeRoleResponse response = client.getAcsResponse(request);
        return response;

    }
	
}
